package bootstrap

import (
	"context"
	"fmt"
	"log/slog"
	"time"

	"gitee.com/jiebaiyou/formflow/model"
	"gitee.com/jiebaiyou/formflow/pkg/storage/redis"
	"gitee.com/jiebaiyou/formflow/pkg/storage/sqlite"
	"gorm.io/gorm/logger"
)

// NewSQLiteDatabase 创建并初始化SQLite数据库连接
func NewSQLiteDatabase(env *Config) sqlite.DB {
	slog.Info("初始化SQLite连接...")

	// 创建带超时的上下文
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	// 从环境配置中获取数据库连接参数
	dbPath := env.SQLITE.DB_PATH
	slog.Info("SQLite文件路径", slog.String("path", dbPath))

	// 配置SQLite连接选项
	options := sqlite.Options{
		Path:     dbPath,
		LogLevel: logger.Warn,
		AutoMigrateModels: []any{
			&model.User{},
			&model.Task{},
		},
	}

	// 创建SQLite客户端
	slog.Info("创建SQLite客户端...")
	client, err := sqlite.NewClient(ctx, options)
	if err != nil {
		slog.Error("创建SQLite客户端失败", slog.String("error", err.Error()))
	}

	slog.Info("SQLite连接初始化成功")
	return client
}

// CloseSQLiteConnection 关闭SQLite数据库连接
func CloseSQLiteConnection() {
	// slog.Info("SQLite使用的是文件连接, 无需显式关闭")
}

// NewRedisDatabase 创建并初始化Redis数据库连接
func NewRedisDatabase(env *Config) redis.Client {
	slog.Info("初始化Redis连接...")

	// 从环境配置中获取Redis连接参数
	redisHost := env.REDIS.HOST
	redisPort := env.REDIS.PORT
	redisUsername := env.REDIS.USERNAME
	redisPassword := env.REDIS.PASSWORD
	redisDB := env.REDIS.DB
	slog.Info("Redis连接参数", slog.String("host", redisHost), slog.String("port", redisPort), slog.Int("db", redisDB))

	// 构建Redis连接URI
	redisURI := fmt.Sprintf("redis://%s:%s", redisHost, redisPort)

	// 如果有用户名和密码, 则添加到URI中
	if redisUsername != "" && redisPassword != "" {
		redisURI = fmt.Sprintf("redis://%s:%s@%s:%s", redisUsername, redisPassword, redisHost, redisPort)
		slog.Info("使用用户名和密码认证方式连接Redis", slog.String("username", redisUsername), slog.String("password", "......"))
	} else if redisPassword != "" {
		redisURI = fmt.Sprintf("redis://:%s@%s:%s", redisPassword, redisHost, redisPort)
		slog.Info("使用密码认证方式连接Redis", slog.String("password", "......"))
	} else {
		slog.Info("使用无认证方式连接Redis")
	}

	// 如果指定了数据库编号, 则添加到URI中
	if redisDB > 0 {
		redisURI = fmt.Sprintf("%s/%d", redisURI, redisDB)
	}

	// 创建Redis客户端
	slog.Info("创建Redis客户端...")
	client, err := redis.NewClient(redisURI)
	if err != nil {
		slog.Error("Redis连接失败", slog.String("error", err.Error()))
		return nil
	}

	// 验证连接是否成功
	slog.Info("验证Redis连接...")
	ctx := context.Background()
	err = client.Ping(ctx)
	if err != nil {
		slog.Error("Redis Ping失败", slog.String("error", err.Error()))
		return nil
	}

	slog.Info("Redis连接初始化成功")

	if env.BASE.INITIAL_DATA_INSTALLED {
		slog.Info("已安装初始数据, 跳过安装...")
	} else {
		slog.Info("未安装初始数据, 开始安装...")
		env.BASE.INITIAL_DATA_INSTALLED = true

	}
	return client
}

// CloseRedisConnection 关闭Redis数据库连接
func CloseRedisConnection(client redis.Client) {
	if client == nil {
		slog.Info("Redis客户端为空, 无需断开连接")
		return
	}

	// 断开连接
	slog.Info("正在断开Redis连接...")
	err := client.Close()
	if err != nil {
		slog.Error("断开Redis连接失败", slog.String("error", err.Error()))
	}

	slog.Info("Redis连接已关闭")
}
